package system

import (
	"errors"
	"fmt"
	"gitee.com/g-qs/gin-vue-admin/server/model/catering"
	"gitee.com/g-qs/gin-vue-admin/server/model/disease"
	"gitee.com/g-qs/gin-vue-admin/server/model/manager"
	systemRes "gitee.com/g-qs/gin-vue-admin/server/model/system/response"
	"gitee.com/g-qs/gin-vue-admin/server/model/user"
	"gitee.com/g-qs/gin-vue-admin/server/plugin/geo/model"
	"strconv"
	"strings"
	"time"

	"gitee.com/g-qs/gin-vue-admin/server/global"
	"gitee.com/g-qs/gin-vue-admin/server/model/common/request"
	"gitee.com/g-qs/gin-vue-admin/server/model/system"
	SystemReq "gitee.com/g-qs/gin-vue-admin/server/model/system/request"
	"gitee.com/g-qs/gin-vue-admin/server/utils"
	"github.com/gofrs/uuid/v5"
	"gorm.io/gorm"
)

//@author: [piexlmax](https://github.com/piexlmax)
//@function: Register
//@description: 用户注册
//@param: u model.SysUser
//@return: userInter system.SysUser, err error

type UserService struct{}

func (userService *UserService) Register(u system.SysUser) (userInter system.SysUser, err error) {
	var user system.SysUser
	if !errors.Is(global.GVA_DB.Where("username = ?", u.Username).First(&user).Error, gorm.ErrRecordNotFound) { // 判断用户名是否注册
		return userInter, errors.New("用户名或手机号已注册")
	}
	if !errors.Is(global.GVA_DB.Where("name = ?", u.Name).First(&user).Error, gorm.ErrRecordNotFound) { // 判断用户名是否注册
		return userInter, errors.New("名称已存在")
	}
	// 否则 附加uuid 密码hash加密 注册
	u.Password = utils.BcryptHash(u.Password)
	u.UUID = uuid.Must(uuid.NewV4())
	err = global.GVA_DB.Create(&u).Error
	return u, err
}

//@author: [piexlmax](https://github.com/piexlmax)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: Login
//@description: 用户登录
//@param: u *model.SysUser
//@return: err error, userInter *model.SysUser

func (userService *UserService) Login(u *system.SysUser) (userInter *system.SysUser, err error) {
	if nil == global.GVA_DB {
		return nil, fmt.Errorf("db not init")
	}

	var user system.SysUser
	err = global.GVA_DB.Where("username = ?", u.Username).Preload("Authorities").Preload("Authority").First(&user).Error
	if err == nil {
		if ok := utils.BcryptCheck(u.Password, user.Password); !ok {
			return nil, errors.New("密码错误")
		}
		MenuServiceApp.UserAuthorityDefaultRouter(&user)
	}
	return &user, err
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: ChangePassword
//@description: 修改用户密码
//@param: u *model.SysUser, newPassword string
//@return: userInter *model.SysUser,err error

func (userService *UserService) ChangePassword(u *system.SysUser, newPassword string) (userInter *system.SysUser, err error) {
	var user system.SysUser
	if err = global.GVA_DB.Where("id = ?", u.ID).First(&user).Error; err != nil {
		return nil, err
	}
	if ok := utils.BcryptCheck(u.Password, user.Password); !ok {
		return nil, errors.New("原密码错误")
	}
	user.Password = utils.BcryptHash(newPassword)
	err = global.GVA_DB.Save(&user).Error
	return &user, err

}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: GetUserInfoList
//@description: 分页获取数据
//@param: info request.PageInfo
//@return: err error, list interface{}, total int64

func (userService *UserService) GetUserInfoList(info request.PageInfo) (list interface{}, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	db := global.GVA_DB.Model(&system.SysUser{})
	var userList []system.SysUser
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Limit(limit).Offset(offset).Preload("Authorities").Preload("Authority").Preload("CreatorInfo").Find(&userList).Error
	return userList, total, err
}

// GetSysUserInfo 根据id获取用户详情
// Author [g-qs](https://github.com/g-qs)
func (userService *UserService) GetSysUserInfo(id uint) (info system.SysUser, err error) {
	err = global.GVA_DB.Where("id = ?", id).Preload("Authorities").Preload("Authority").Preload("CreatorInfo").First(&info).Error
	return
}

// GetServiceCenterList 分页获取服务中心列表
// Author [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetServiceCenterList(info SystemReq.BranchSearch) (list interface{}, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	db := global.GVA_DB.Model(&system.SysUser{}).Where("authority_id = ?", 333)
	var userList []system.SysUser
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.Name != "" {
		db = db.Where("name LIKE ?", "%"+info.Name+"%")
	}
	if info.NickName != "" {
		db = db.Where("nick_name LIKE ?", "%"+info.NickName+"%")
	}
	if info.Phone != "" {
		db = db.Where("phone LIKE ?", "%"+info.Phone+"%")
	}
	if info.Province != "" {
		db = db.Where("province = ?", info.Province)
	}
	if info.City != "" {
		db = db.Where("city = ?", info.City)
	}
	if info.Area != "" {
		db = db.Where("area = ?", info.Area)
	}
	if info.Addr != "" {
		db = db.Where("addr LIKE ?", "%"+info.Addr+"%")
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Limit(limit).Offset(offset).Preload("Authorities").Preload("Authority").Preload("CreatorInfo").Find(&userList).Error
	return userList, total, err
}

// GetHealthManageCenterList 分页获取健管中心数据
// Author [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetHealthManageCenterList(info SystemReq.BranchSearch) (list interface{}, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	db := global.GVA_DB.Model(&system.SysUser{}).Where("authority_id = ? AND creator = ?", 444, info.Creator)
	var userList []system.SysUser
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.Name != "" {
		db = db.Where("name LIKE ?", "%"+info.Name+"%")
	}
	if info.NickName != "" {
		db = db.Where("nick_name LIKE ?", "%"+info.NickName+"%")
	}
	if info.Phone != "" {
		db = db.Where("phone LIKE ?", "%"+info.Phone+"%")
	}
	if info.Province != "" {
		db = db.Where("province = ?", info.Province)
	}
	if info.City != "" {
		db = db.Where("city = ?", info.City)
	}
	if info.Area != "" {
		db = db.Where("area = ?", info.Area)
	}
	if info.Addr != "" {
		db = db.Where("addr LIKE ?", "%"+info.Addr+"%")
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Limit(limit).Offset(offset).Preload("Authorities").Preload("Authority").Preload("CreatorInfo").Find(&userList).Error
	return userList, total, err
}

// GetAllServiceStationList 分页获取全部服务站列表【超管】
// Author [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetAllServiceStationList(info SystemReq.BranchSearch) (list interface{}, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	db := global.GVA_DB.Model(&system.SysUser{}).Where("authority_id = 444")
	var userList []system.SysUser
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.Name != "" {
		db = db.Where("name LIKE ?", "%"+info.Name+"%")
	}
	if info.NickName != "" {
		db = db.Where("nick_name LIKE ?", "%"+info.NickName+"%")
	}
	if info.Phone != "" {
		db = db.Where("phone LIKE ?", "%"+info.Phone+"%")
	}
	if info.Province != "" {
		db = db.Where("province = ?", info.Province)
	}
	if info.City != "" {
		db = db.Where("city = ?", info.City)
	}
	if info.Area != "" {
		db = db.Where("area = ?", info.Area)
	}
	if info.Addr != "" {
		db = db.Where("addr LIKE ?", "%"+info.Addr+"%")
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Limit(limit).Offset(offset).Preload("Authorities").Preload("Authority").Preload("CreatorInfo").Find(&userList).Error
	return userList, total, err
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: SetUserAuthority
//@description: 设置一个用户的权限
//@param: uuid uuid.UUID, authorityId string
//@return: err error

func (userService *UserService) SetUserAuthority(id uint, authorityId uint) (err error) {
	assignErr := global.GVA_DB.Where("sys_user_id = ? AND sys_authority_authority_id = ?", id, authorityId).First(&system.SysUserAuthority{}).Error
	if errors.Is(assignErr, gorm.ErrRecordNotFound) {
		return errors.New("该用户无此角色")
	}
	err = global.GVA_DB.Where("id = ?", id).First(&system.SysUser{}).Update("authority_id", authorityId).Error
	return err
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: SetUserAuthorities
//@description: 设置一个用户的权限
//@param: id uint, authorityIds []string
//@return: err error

func (userService *UserService) SetUserAuthorities(id uint, authorityIds []uint) (err error) {
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		TxErr := tx.Delete(&[]system.SysUserAuthority{}, "sys_user_id = ?", id).Error
		if TxErr != nil {
			return TxErr
		}
		var useAuthority []system.SysUserAuthority
		for _, v := range authorityIds {
			useAuthority = append(useAuthority, system.SysUserAuthority{
				SysUserId: id, SysAuthorityAuthorityId: v,
			})
		}
		TxErr = tx.Create(&useAuthority).Error
		if TxErr != nil {
			return TxErr
		}
		TxErr = tx.Where("id = ?", id).First(&system.SysUser{}).Update("authority_id", authorityIds[0]).Error
		if TxErr != nil {
			return TxErr
		}
		// 返回 nil 提交事务
		return nil
	})
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: DeleteUser
//@description: 删除用户
//@param: id float64
//@return: err error

func (userService *UserService) DeleteUser(id int) (err error) {
	var user system.SysUser
	err = global.GVA_DB.Where("id = ?", id).Delete(&user).Error
	if err != nil {
		return err
	}
	err = global.GVA_DB.Delete(&[]system.SysUserAuthority{}, "sys_user_id = ?", id).Error
	return err
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: SetUserInfo
//@description: 设置用户信息
//@param: reqUser model.SysUser
//@return: err error, user model.SysUser

func (userService *UserService) SetUserInfo(req system.SysUser) error {
	//if !errors.Is(global.GVA_DB.Where("name = ?", req.Name).First(&req).Error, gorm.ErrRecordNotFound) { // 判断用户名称是否存在
	//	return errors.New("名称已存在")
	//}
	// 基础字段
	selectFields := []string{"updated_at", "name", "nick_name", "header_img", "phone", "email", "side_mode", "enable", "province", "city", "area", "addr"}
	updates := map[string]interface{}{
		"updated_at": time.Now(),
		"name":       req.Name,
		"nick_name":  req.NickName,
		"header_img": req.HeaderImg,
		"phone":      req.Phone,
		"email":      req.Email,
		"side_mode":  req.SideMode,
		"enable":     req.Enable,
		"province":   req.Province,
		"city":       req.City,
		"area":       req.Area,
		"addr":       req.Addr,
	}
	// 仅当密码非空时更新密码（假设不允许空密码）
	if req.Password != "" {
		selectFields = append(selectFields, "password")
		updates["password"] = utils.BcryptHash(req.Password)
	}
	return global.GVA_DB.Debug().Model(&system.SysUser{}).Select(selectFields).Where("id = ?", req.ID).Updates(updates).Error
}

// SetUserEnable 设置用户状态
func (userService *UserService) SetUserEnable(req system.SysUser) error {
	return global.GVA_DB.Model(&system.SysUser{}).
		Select("updated_at", "name", "nick_name", "header_img", "phone", "email", "sideMode", "enable", "province", "city", "area", "addr").
		Where("id=?", req.ID).
		Update("enable", req.Enable).Error
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: SetUserInfo
//@description: 设置用户信息
//@param: reqUser model.SysUser
//@return: err error, user model.SysUser

func (userService *UserService) SetSelfInfo(req system.SysUser) error {
	//if !errors.Is(global.GVA_DB.Where("name = ?", req.Name).First(&req).Error, gorm.ErrRecordNotFound) { // 判断用户名称是否存在
	//	return errors.New("名称已存在")
	//}
	return global.GVA_DB.Model(&system.SysUser{}).
		Where("id=?", req.ID).
		Updates(req).Error
}

//@author: [piexlmax](https://github.com/piexlmax)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: GetUserInfo
//@description: 获取用户信息
//@param: uuid uuid.UUID
//@return: err error, user system.SysUser

func (userService *UserService) GetUserInfo(uuid uuid.UUID) (user system.SysUser, err error) {
	var reqUser system.SysUser
	err = global.GVA_DB.Preload("Authorities").Preload("Authority").First(&reqUser, "uuid = ?", uuid).Error
	if err != nil {
		return reqUser, err
	}
	MenuServiceApp.UserAuthorityDefaultRouter(&reqUser)
	return reqUser, err
}

//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: FindUserById
//@description: 通过id获取用户信息
//@param: id int
//@return: err error, user *model.SysUser

func (userService *UserService) FindUserById(id int) (user *system.SysUser, err error) {
	var u system.SysUser
	err = global.GVA_DB.Where("id = ?", id).First(&u).Error
	return &u, err
}

//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: FindUserByUuid
//@description: 通过uuid获取用户信息
//@param: uuid string
//@return: err error, user *model.SysUser

func (userService *UserService) FindUserByUuid(uuid string) (user *system.SysUser, err error) {
	var u system.SysUser
	if err = global.GVA_DB.Where("uuid = ?", uuid).First(&u).Error; err != nil {
		return &u, errors.New("用户不存在")
	}
	return &u, nil
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: resetPassword
//@description: 修改用户密码
//@param: ID uint
//@return: err error

func (userService *UserService) ResetPassword(ID uint) (err error) {
	err = global.GVA_DB.Model(&system.SysUser{}).Where("id = ?", ID).Update("password", utils.BcryptHash("123456")).Error
	return err
}

// GetServiceCenterMapData // 获取服务中心地图数据
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetServiceCenterMapData() (list []systemRes.CountNum, err error) {
	var services []system.SysUser
	var cities []model.GeoCity
	var healthManagers []manager.FdHealthManager
	// 查询所有的服务中心
	// Select("(SELECT name FROM geo_cities WHERE code = `sys_users`.city) AS name,id,city").
	if servicesErr := global.GVA_DB.Select("(SELECT name FROM geo_cities WHERE code = `sys_users`.city) AS name,id,city").Where("authority_id = ?", 333).Find(&services).Error; servicesErr != nil {
		return list, servicesErr
	}
	// 查询城市信息
	if citiesErr := global.GVA_DB.Where("code IN ? ", getSysUserCityIDs(services)).Find(&cities).Error; citiesErr != nil {
		return list, citiesErr
	}
	// 构建城市经纬度映射
	geoCoordMap := make(map[string][2]float64)
	for _, city := range cities {
		geoCoordMap[city.Code] = [2]float64{city.Longitude, city.Latitude}
	}
	// 统计每个服务中心下的健管师数量
	for _, serviceCenter := range services {
		global.GVA_DB.Where("store_id IN (SELECT id FROM sys_users WHERE creator = ?)", serviceCenter.ID).Find(&healthManagers)
		// 健管师数量统计
		list = append(list, systemRes.CountNum{
			Name:      serviceCenter.Name,
			Value:     uint(len(healthManagers)),
			LonAndLat: geoCoordMap[serviceCenter.City],
		})
	}
	return
}

// GetStationsMapDataByHm // 获取下属服务站地图数据【服务中心】
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetStationsMapDataByHm(CentreID uint) (info systemRes.StationMapData, err error) {
	var stations []system.SysUser
	var cities []model.GeoCity
	var provinces model.GeoProvince
	var healthManagers []manager.FdHealthManager
	// 查询所有的服务站
	if servicesErr := global.GVA_DB.Select("(SELECT name FROM geo_cities WHERE code = `sys_users`.city) AS name,id,province,city").Where("authority_id = 444 AND creator = ?", CentreID).Find(&stations).Error; servicesErr != nil {
		return info, servicesErr
	}
	var countNums []systemRes.CountNum
	// 查询城市信息
	if citiesErr := global.GVA_DB.Where("code IN ? ", getSysUserCityIDs(stations)).Find(&cities).Error; citiesErr != nil {
		return info, citiesErr
	}
	// 查询省份信息
	if provincesErr := global.GVA_DB.Where("code IN ? ", getSysUserProvinceIDs(stations)).First(&provinces).Error; provincesErr != nil {
		return info, provincesErr
	}
	// 构建城市经纬度映射
	geoCoordMap := make(map[string][2]float64)
	for _, city := range cities {
		geoCoordMap[city.Code] = [2]float64{city.Longitude, city.Latitude}
	}
	// 统计每个服务中心下的健管师数量
	for _, station := range stations {
		global.GVA_DB.Where("store_id = ?", station.ID).Find(&healthManagers)
		// 健管师数量统计
		countNums = append(countNums, systemRes.CountNum{
			Name:      station.Name,
			Value:     uint(len(healthManagers)),
			LonAndLat: geoCoordMap[station.City],
		})
	}
	centre := [2]float64{}
	var provinceName string
	centre = [2]float64{provinces.Longitude, provinces.Latitude}
	provinceName = provinces.Name
	// 构造最终返回的数据
	info = systemRes.StationMapData{
		CountNums: countNums,
		Centre:    centre,
		Province:  provinceName,
	}
	return
}

// GetStationsMapDataByUser // 获取下属服务站地图数据【服务中心】
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetStationsMapDataByUser(CentreID uint) (info systemRes.StationMapData, err error) {
	var stations []system.SysUser
	var cities []model.GeoCity
	var provinces model.GeoProvince
	var users []user.User
	// 查询所有的服务站
	if servicesErr := global.GVA_DB.Select("(SELECT name FROM geo_cities WHERE code = `sys_users`.city) AS name,id,province,city").Where("authority_id = 444 AND creator = ?", CentreID).Find(&stations).Error; servicesErr != nil {
		return info, servicesErr
	}
	var countNums []systemRes.CountNum
	// 查询城市信息
	if citiesErr := global.GVA_DB.Where("code IN ? ", getSysUserCityIDs(stations)).Find(&cities).Error; citiesErr != nil {
		return info, citiesErr
	}
	// 查询城市信息
	if provincesErr := global.GVA_DB.Where("code IN ? ", getSysUserProvinceIDs(stations)).First(&provinces).Error; provincesErr != nil {
		return info, provincesErr
	}
	// 构建城市经纬度映射
	geoCoordMap := make(map[string][2]float64)
	for _, city := range cities {
		geoCoordMap[city.Code] = [2]float64{city.Longitude, city.Latitude}
	}
	// 统计每个服务站下的用户数量
	for _, station := range stations {
		global.GVA_DB.Where("service_center_id = ?", station.ID).Find(&users)
		// 健管师数量统计
		countNums = append(countNums, systemRes.CountNum{
			Name:      station.Name,
			Value:     uint(len(users)),
			LonAndLat: geoCoordMap[station.City],
		})
	}
	centre := [2]float64{}
	var provinceName string
	centre = [2]float64{provinces.Longitude, provinces.Latitude}
	provinceName = provinces.Name
	// 构造最终返回的数据
	info = systemRes.StationMapData{
		CountNums: countNums,
		Centre:    centre,
		Province:  provinceName,
	}
	return
}

// GetServiceStationMapData // 获取服务站地图数据
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetServiceStationMapData() (list []systemRes.CountNum, err error) {
	var stations []system.SysUser
	var cities []model.GeoCity
	var users []user.User
	// 查询所有的服务站
	if stationsErr := global.GVA_DB.Select("(SELECT name FROM geo_cities WHERE code = `sys_users`.city) AS name,id,city").Where("authority_id = ?", 444).Find(&stations).Error; stationsErr != nil {
		return list, stationsErr
	}
	// 查询城市信息
	if citiesErr := global.GVA_DB.Where("code IN ? ", getSysUserCityIDs(stations)).Find(&cities).Error; citiesErr != nil {
		return list, citiesErr
	}
	// 构建城市经纬度映射
	geoCoordMap := make(map[string][2]float64)
	for _, city := range cities {
		geoCoordMap[city.Code] = [2]float64{city.Longitude, city.Latitude}
	}
	// 统计每个服务中心下的用户数
	for _, v := range stations {
		global.GVA_DB.Where("service_center_id IN (?)", v.ID).Find(&users)
		// 健管师数量统计
		list = append(list, systemRes.CountNum{
			Name:      v.Name,
			Value:     uint(len(users)),
			LonAndLat: geoCoordMap[v.City],
		})
	}
	return
}

// GetServiceStationRank // 获取服务中心下服务站数量排名
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetServiceStationRank() (list []systemRes.StatisticalResults, err error) {
	// 查询每个服务中心下的健管中心数量
	err = global.GVA_DB.Model(&system.SysUser{}).
		Select("`sys_users`.name, COUNT(b.id) AS value, GROUP_CONCAT(b.id) AS IDs").
		Joins("LEFT JOIN sys_users AS b ON b.creator = `sys_users`.id").
		Where("b.authority_id = 444 AND `sys_users`.authority_id = 333").
		Group("`sys_users`.id").
		Order("value DESC").
		Scan(&list).Error
	return
}

// GetHealthManagerRank // 获取服务中心下健管师数量排名
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetHealthManagerRank() (list []systemRes.StatisticalResults, err error) {
	err = global.GVA_DB.Model(&system.SysUser{}).
		Select("`sys_users`.name, COUNT(c.hm_id) AS value, GROUP_CONCAT(c.hm_id) AS IDs").
		Joins("LEFT JOIN sys_users AS b ON b.creator = `sys_users`.id").
		Joins("LEFT JOIN fd_health_manager AS c ON c.store_id = b.id").
		Where("b.authority_id = 444 AND `sys_users`.authority_id = 333").
		Group("`sys_users`.id").
		Order("value DESC").
		Scan(&list).Error
	return
}

// GetStationsRankByHmNum 获取服务站排名根据健管师数量【服务中心】
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetStationsRankByHmNum(CentreID uint) (list []systemRes.StatisticalResults, err error) {
	err = global.GVA_DB.Model(&system.SysUser{}).
		Select("`sys_users`.`name`, COUNT(b.hm_id) AS `value`, GROUP_CONCAT(b.hm_id) AS IDs").
		Joins("LEFT JOIN fd_health_manager AS b ON b.`store_id` = `sys_users`.`id`").
		Where("`sys_users`.`authority_id` = 444 AND `sys_users`.`creator` = ?", CentreID).
		Group("`sys_users`.id").
		Order("`value` DESC").
		Scan(&list).Error
	return
}

// GetUserRank // 获取服务中心下用户数量排名
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetUserRank() (list []systemRes.StatisticalResults, err error) {
	err = global.GVA_DB.Model(&system.SysUser{}).
		Select("`sys_users`.name, COUNT(c.id) AS value, GROUP_CONCAT(c.id) AS IDs").
		Joins("LEFT JOIN sys_users AS b ON b.creator = `sys_users`.id").
		Joins("LEFT JOIN fd_user AS c ON c.service_center_id = b.id").
		Where("b.authority_id = 444 AND `sys_users`.authority_id = 333").
		Group("`sys_users`.id").
		Order("value DESC").
		Scan(&list).Error
	return
}

// GetServiceCenterDiseaseList // 获取服务中心主病症列表
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetServiceCenterDiseaseList() (list []systemRes.MainDiseaseList, err error) {
	var services []system.SysUser
	var stations []system.SysUser
	var users []user.User
	var records []disease.DiseaseReportRecord
	// 查询所有的服务中心
	if servicesErr := global.GVA_DB.Where("authority_id = ?", 333).Find(&services).Error; servicesErr != nil {
		return list, servicesErr
	}
	// 统计每个服务中心下的用户数量
	for _, serviceCenter := range services {
		// 查询与当前服务中心关联的所有服务站
		global.GVA_DB.Where("creator = ?", serviceCenter.ID).Find(&stations)
		var userIDs []uint
		for _, stationValue := range stations {
			// 查询与当前服务站关联的所有用户
			global.GVA_DB.Table("fd_user USE INDEX (service_center_id)").Where("service_center_id = ?", stationValue.ID).Find(&users)
			for _, userValue := range users {
				userIDs = append(userIDs, userValue.ID)
			}
		}
		// 查询与当前用户关联的所有病症报告记录
		global.GVA_DB.Table("fd_disease_report_record USE INDEX (uid)").
			Joins("INNER JOIN ( SELECT uid, MAX( created_at ) AS latest_date FROM fd_disease_report_record WHERE uid IN (?) GROUP BY uid ) latest_records ON fd_disease_report_record.uid = latest_records.uid", userIDs).
			Where("fd_disease_report_record.created_at = latest_records.latest_date").Find(&records)
		// 统计疾病出现次数
		diseaseCounts := map[string]int{}
		for _, record := range records {
			diseases := strings.Split(record.BzIDs, ",")
			for _, diseaseID := range diseases {
				diseaseCounts[diseaseID]++
			}
		}
		// 找出出现次数最多的疾病
		maxCount := 0
		mainDiseaseID := ""
		for diseaseID, count := range diseaseCounts {
			if count > maxCount {
				maxCount = count
				mainDiseaseID = diseaseID
			}
		}
		// 查询主要疾病名称
		var bz disease.Disease
		if bzErr := global.GVA_DB.First(&bz, "id = ?", mainDiseaseID).Error; bzErr != nil {
			continue
		}
		list = append(list, systemRes.MainDiseaseList{
			Name:    serviceCenter.Name,
			Disease: bz.Name,
		})
	}
	return
}

// GetCompletePlanUserRank // 获取服务站完成方案用户排行
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetCompletePlanUserRank() (list []systemRes.StatisticalResults, err error) {
	endOfDay := time.Now().Format("2006-01-02")
	startOfDay := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
	if err = global.GVA_DB.Model(&catering.Food{}).
		Select("sys_users.name, COUNT(*) AS value, GROUP_CONCAT(fd_user.id) AS IDs").
		Joins("JOIN fd_user ON `fd_food`.user_id = fd_user.id").
		Joins("JOIN sys_users ON fd_user.service_center_id = sys_users.id").
		Where("`fd_food`.created_at >= ? AND `fd_food`.created_at < ?", startOfDay, endOfDay).
		Where("`fd_food`.breakfast IS NOT NULL AND `fd_food`.lunch IS NOT NULL AND `fd_food`.dinner IS NOT NULL AND `fd_food`.brain IS NOT NULL AND `fd_food`.sport IS NOT NULL").
		Group("sys_users.name").Order("value DESC").
		Scan(&list).Error; err != nil {
		return list, nil
	}
	return
}

// GetStationsRankByCpuNum // 获取服务站排名根据完成方案用户数量【服务中心】
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetStationsRankByCpuNum(CentreID uint) (list []systemRes.StatisticalResults, err error) {
	endOfDay := time.Now().Format("2006-01-02")
	startOfDay := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
	if err = global.GVA_DB.Model(&catering.Food{}).
		Select("sys_users.name, COUNT(*) AS value, GROUP_CONCAT(fd_user.id) AS IDs").
		Joins("JOIN fd_user ON `fd_food`.user_id = fd_user.id").
		Joins("JOIN sys_users ON fd_user.service_center_id = sys_users.id").
		Where("`fd_food`.created_at BETWEEN ? AND ?", startOfDay, endOfDay).
		Where("`sys_users`.creator = ?", CentreID).
		Where("`fd_food`.breakfast IS NOT NULL AND `fd_food`.lunch IS NOT NULL AND `fd_food`.dinner IS NOT NULL AND `fd_food`.brain IS NOT NULL AND `fd_food`.sport IS NOT NULL").
		Group("sys_users.name").Order("value DESC").
		Scan(&list).Error; err != nil {
		return list, nil
	}
	return
}

// GetStationHealthManagerRank // 获取服务站健管师数量排名
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetStationHealthManagerRank() (list []systemRes.StatisticalResults, err error) {
	// 查询每个服务中心下的健管中心数量
	err = global.GVA_DB.Model(&system.SysUser{}).
		Select("`sys_users`.name, COUNT(c.hm_id) AS value, GROUP_CONCAT(c.hm_id) AS IDs").
		Joins("LEFT JOIN fd_health_manager AS c ON c.store_id = `sys_users`.id").
		Where("`sys_users`.authority_id = 444").
		Group("`sys_users`.id").
		Order("value DESC").
		Scan(&list).Error
	return
}

// GetStationRankByUserNum 获取服务站排名根据用户数量【服务中心】
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetStationRankByUserNum(CentreID uint) (list []systemRes.StatisticalResults, err error) {
	err = global.GVA_DB.Model(&system.SysUser{}).
		Select("`sys_users`.name, COUNT(c.id) AS value, GROUP_CONCAT(c.id) AS IDs").
		Joins("LEFT JOIN fd_user AS c ON c.service_center_id = `sys_users`.id").
		Where("`sys_users`.authority_id = 444 AND `sys_users`.creator = ?", CentreID).
		Group("`sys_users`.id").
		Order("value DESC").
		Scan(&list).Error
	return
}

// GetStationUserRank // 获取服务站用户数量排名
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetStationUserRank() (list []systemRes.StatisticalResults, err error) {
	err = global.GVA_DB.Model(&system.SysUser{}).
		Select("`sys_users`.name, COUNT(c.id) AS value, GROUP_CONCAT(c.id) AS IDs").
		Joins("LEFT JOIN fd_user AS c ON c.service_center_id = `sys_users`.id").
		Where("`sys_users`.authority_id = 444").
		Group("`sys_users`.id").
		Order("value DESC").
		Scan(&list).Error
	return
}

// GetStationDiseaseList // 获取服务站主病症列表
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetStationDiseaseList() (list []systemRes.MainDiseaseList, err error) {
	// 1. 获取所有服务站
	var stations []system.SysUser
	if err := global.GVA_DB.Where("authority_id = ?", 444).Find(&stations).Error; err != nil {
		return nil, err
	}
	if len(stations) == 0 {
		return []systemRes.MainDiseaseList{}, nil
	}

	// 收集服务站ID
	stationIDs := make([]uint, 0, len(stations))
	for _, station := range stations {
		stationIDs = append(stationIDs, station.ID)
	}

	// 2. 批量获取所有服务站的用户
	var users []user.User
	if err := global.GVA_DB.Where("service_center_id IN ?", stationIDs).Find(&users).Error; err != nil {
		return nil, err
	}
	if len(users) == 0 {
		return []systemRes.MainDiseaseList{}, nil
	}

	// 构建用户ID到服务站的映射和用户ID列表
	userIDToStationID := make(map[uint]uint, len(users))
	userIDs := make([]uint, 0, len(users))
	for _, user := range users {
		userIDToStationID[user.ID] = user.ServiceCenterID
		userIDs = append(userIDs, user.ID)
	}

	// 3. 批量获取所有用户的最后一条报告记录（优化查询）
	var records []disease.DiseaseReportRecord
	subQuery := global.GVA_DB.Model(&disease.DiseaseReportRecord{}).
		Select("uid, MAX(created_at) as latest_date").
		Where("uid IN ?", userIDs).
		Group("uid")

	if err := global.GVA_DB.Table("fd_disease_report_record as r").
		Joins("INNER JOIN (?) AS l ON r.uid = l.uid AND r.created_at = l.latest_date", subQuery).
		Find(&records).Error; err != nil {
		return nil, err
	}

	// 4. 统计病症出现次数（内存计算）
	// stationID -> (diseaseID -> count)
	diseaseStats := make(map[uint]map[string]int)
	for _, record := range records {
		stationID := userIDToStationID[record.Uid]
		if stationID == 0 {
			continue
		}

		if _, ok := diseaseStats[stationID]; !ok {
			diseaseStats[stationID] = make(map[string]int)
		}

		for _, diseaseID := range strings.Split(record.BzIDs, ",") {
			if diseaseID == "" {
				continue
			}
			diseaseStats[stationID][diseaseID]++
		}
	}

	// 5. 收集所有需要查询的病症ID
	var diseaseIDs []string
	for _, stats := range diseaseStats {
		for diseaseID := range stats {
			diseaseIDs = append(diseaseIDs, diseaseID)
		}
	}

	// 6. 批量获取病症名称
	var diseases []disease.Disease
	if err = global.GVA_DB.Where("id IN ?", diseaseIDs).Find(&diseases).Error; err != nil {
		return nil, err
	}

	diseaseNameMap := make(map[string]string, len(diseases))
	for _, d := range diseases {
		diseaseNameMap[strconv.Itoa(int(d.ID))] = d.Name
	}

	// 7. 构建最终结果
	list = make([]systemRes.MainDiseaseList, 0, len(stations))
	for _, station := range stations {
		stats, ok := diseaseStats[station.ID]
		if !ok || len(stats) == 0 {
			continue
		}

		// 找出最大出现次数的病症
		maxCount := 0
		var mainDiseaseID string
		for diseaseID, count := range stats {
			if count > maxCount || (count == maxCount && diseaseID < mainDiseaseID) {
				maxCount = count
				mainDiseaseID = diseaseID
			}
		}

		if mainDiseaseID != "" {
			list = append(list, systemRes.MainDiseaseList{
				Name:    station.Name,
				Disease: diseaseNameMap[mainDiseaseID],
			})
		}
	}
	return
}

// GetCentreDiseaseList 获取服务中心主病症列表【服务中心】
// Author: [g-qs](https://gitee.com/g-qs)
func (userService *UserService) GetCentreDiseaseList(CentreID uint) (list []systemRes.MainDiseaseList, err error) {
	var stations []system.SysUser
	var users []user.User
	var records []disease.DiseaseReportRecord
	// 查询所有的服务站
	if stationsErr := global.GVA_DB.Where("authority_id = 444 AND creator = ?", CentreID).Find(&stations).Error; stationsErr != nil {
		return list, stationsErr
	}
	for _, stationValue := range stations {
		// 查询与当前服务站关联的所有用户
		global.GVA_DB.Table("fd_user USE INDEX (service_center_id)").Where("service_center_id = ?", stationValue.ID).Find(&users)
		var userIDs []uint
		for _, userValue := range users {
			userIDs = append(userIDs, userValue.ID)
		}
		// 查询与当前用户关联的所有病症报告记录
		global.GVA_DB.Table("fd_disease_report_record USE INDEX (uid)").
			Joins("INNER JOIN ( SELECT uid, MAX( created_at ) AS latest_date FROM fd_disease_report_record WHERE uid IN (?) GROUP BY uid ) latest_records ON fd_disease_report_record.uid = latest_records.uid", userIDs).
			Where("fd_disease_report_record.created_at = latest_records.latest_date").Find(&records)
		// 统计疾病出现次数
		diseaseCounts := map[string]int{}
		for _, record := range records {
			diseases := strings.Split(record.BzIDs, ",")
			for _, diseaseID := range diseases {
				diseaseCounts[diseaseID]++
			}
		}
		// 找出出现次数最多的疾病
		maxCount := 0
		mainDiseaseID := ""
		for diseaseID, count := range diseaseCounts {
			if count > maxCount {
				maxCount = count
				mainDiseaseID = diseaseID
			}
		}
		// 查询主要疾病名称
		var bz disease.Disease
		if bzErr := global.GVA_DB.First(&bz, "id = ?", mainDiseaseID).Error; bzErr != nil {
			continue
		}
		list = append(list, systemRes.MainDiseaseList{
			Name:    stationValue.Name,
			Disease: bz.Name,
		})
	}
	return
}

// GetServiceStationListByIDs 根据ID集合获取用户列表【超管】
func (userService *UserService) GetServiceStationListByIDs(info SystemReq.ServiceStation) (list []systemRes.ServiceStations, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&system.SysUser{})
	if info.UIDs != "" {
		IDsStr := strings.Trim(info.UIDs, "[]")
		IDsArr := strings.Split(IDsStr, ",")
		db = db.Where("sys_users.id IN (?)", IDsArr)
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}
	err = db.Select("sys_users.`id`, sys_users.`nick_name`, sys_users.`phone`, sys_users.`name`, b.`name` AS serviceCenter, " +
		"(SELECT name FROM geo_provinces WHERE code = sys_users.province) AS province, " +
		"(SELECT name FROM geo_cities WHERE code = sys_users.city) AS city, " +
		"(SELECT name FROM geo_areas WHERE code = sys_users.area) AS area").
		Joins("LEFT JOIN sys_users AS b ON sys_users.`creator` = b.id").
		Order("sys_users.id ASC").
		Scan(&list).Error
	return
}

func getSysUserCityIDs(users []system.SysUser) []string {
	ids := make([]string, len(users))
	for i, g := range users {
		ids[i] = g.City
	}
	return ids
}

func getSysUserProvinceIDs(users []system.SysUser) []string {
	ids := make([]string, len(users))
	for i, g := range users {
		ids[i] = g.Province
	}
	return ids
}
